package lib.paxos;

import java.io.Serializable;
import java.util.List;

import lib.ArgumentValidator;

/**
 * SyncMessage is used to bring two paxos servers in sync,
 * regarding their state information
 * @author abhip
 *
 */
public class SyncMessage implements Serializable
{

    /**
     * serialVersionUID is a universal version identifier for a Serializable
     * class. Deserialization uses this number to ensure that a loaded class
     * corresponds exactly to a serialized object. If no match is found during
     * deserialization, an InvalidClassException is thrown.
     */
    private static final long serialVersionUID = 8319126534177904987L;

    private List<RoundInfo> missingRoundInfos;
    private int roundID;
    private SequenceID sequenceID;

    public SyncMessage(
            int roundID,
            SequenceID sequenceID,
            List<RoundInfo> missingRoundInfos)
    {
        ArgumentValidator.IsGreaterThanOrEqualTo("roundID", roundID, 0);
        ArgumentValidator.IsNotNull("sequenceID", sequenceID);
        ArgumentValidator.IsNotNull("missingRoundInfos", missingRoundInfos);
        ArgumentValidator.IsGreaterThan("missingRoundInfos.size()", missingRoundInfos.size(), 0);

        this.roundID = roundID;
        this.sequenceID = sequenceID;
        this.missingRoundInfos = missingRoundInfos;
    }

    public List<RoundInfo> MissingRoundInfos()
    {
        return missingRoundInfos;
    }

    public int RoundID()
    {
        return roundID;
    }

    public SequenceID SequenceID()
    {
        return sequenceID;
    }

    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder(String.format(
                "roundID: %d, sequenceID: %s, missingRoundInfos:",
                roundID,
                sequenceID.toString()));

        if (missingRoundInfos != null)
        {
            for (int i = 0; i < missingRoundInfos.size(); ++i)
            {
                sb.append(missingRoundInfos.get(i).toString());
                sb.append(", ");
            }
        }

        return sb.toString();
    }
}
